package com.sale.plugins;

import com.apache.api.manager.ProxyManager;
import com.apache.api.vo.ParamsVo;
import com.apache.api.vo.ResultEntity;
import com.apache.cache.util.Validator;
import com.apache.database.constant.SpringContextLoader;
import com.apache.exception.BusinessException;
import com.apache.funds.common.FundsUtil;
import com.apache.funds.common.NumberUtil;
import com.apache.funds.vo.UserFundsVo;
import com.apache.ius.plugin.CustomMethodPlugin;
import com.apache.ius.plugin.IusPluginUtil;
import com.apache.ius.plugin.UtilPlugin;
import com.apache.match.common.Constant;
import com.apache.tools.DataMap;
import com.apache.tools.NumberUtils;
import net.sf.json.JSONObject;
import org.apache.log4j.Logger;

import java.util.*;

/**
 * 申购中签扣款
 *
 * @author admin
 */
public class SaleAllocationPayPluginImpl implements CustomMethodPlugin {

    private Logger log = Logger.getLogger(getClass());

    @SuppressWarnings({"unchecked", "rawtypes"})
    @Override
    public Object beforeInvoke(Map<String, Object> param) {
        log.info("start->> 【发售交易】申购中签扣款开始");
        log.info("start->> 接收参数：" + param);
        //获取参数（活动ID）
        String saleId = String.valueOf(param.get("trsSale.w_saleId"));
        if (Validator.isNull(saleId)) {
            throw new BusinessException("saleId参数缺失！");
        }
        List<DataMap> payAmount = (List<DataMap>) getPayAmount(saleId);

        String retFlag = "F";
        String retMsg = "中签扣款失败";

        Map<String, String> userSettleNoMap = new HashMap<String, String>();

        for (int i = 0; i < payAmount.size(); i++) {
            if (null != payAmount.get(i)) {
                DataMap obj = payAmount.get(i);
                String userEname = String.valueOf(obj.get("userOwner"));
                double price = NumberUtils.getDouble(String.valueOf(obj.get("price")), 0, true);
                double num = NumberUtils.getDouble(String.valueOf(obj.get("nums")), 0, true);
                double money = NumberUtils.multiply(price, num);
                String numberId = String.valueOf(obj.get("numberId"));

                if (!userSettleNoMap.containsKey(userEname)) {
                    userSettleNoMap.put(userEname, getUserSettleNo(userEname));
                }
                String userSettleNo = userSettleNoMap.get(userEname);

                //获取对应资金账户余额
                UserFundsVo userVo = FundsUtil.selectFundsMyMoneyByCache(userSettleNo);
                if (null == userVo) {
                    log.info("未获取到用户[" + userEname + "]资金余额信息！");
                    continue;
                }
                double useMoney = NumberUtils.divide(userVo.getM1(), 100, 2);
                //用户金额小于单价，不能购买
                if (useMoney < money) {
                    retFlag = "F";
                    retMsg = "中签扣款失败，余额不足";
                    log.info("用户[" + userEname + "]资金可余额[" + useMoney + "]不足[" + money
                            + "]申购中签扣款，故扣款失败！");
                } else {

                    //扣款操作
                    boolean fmreuslt = fundMove(userSettleNo, money);
                    if (fmreuslt) {
                        retFlag = "T";
                        retMsg = "中签扣款成功";
                    } else {
                        retFlag = "F";
                        retMsg = "中签扣款失败";
                    }
                    log.info((i + 1) + ".申购中签扣款：从[" + userEname + "]的资金账号[" + userSettleNo + "]中扣除["
                            + money + "]。" + retMsg);
                }
                //更改当前对象的配号信息
                Map<String, Object> params = new HashMap<String, Object>();
                params.put("trsNumbers.isPay", retFlag);
                params.put("trsNumbers.remark", retMsg);
                params.put("trsNumbers.w_numberId", numberId);
                params.put("trsBuy.w_saleId", saleId);
                params.put("trsBuy.buyStatus", "40");//申购表，更改申购状态为扣款完成
                updatePayStatus(params);
            }
        }
        return null;
    }

    /**
     * 根据登录账号获取资金账号
     *
     * @param createUserEname
     * @return
     */
    private String getUserSettleNo(String createUserEname) {
        ResultEntity ret = FundsUtil.selectFundsMyAccountByCreateUserEname(createUserEname);
        if ("true".equals(ret.getResult()) && ret.getEntity() != null) {
            JSONObject svmUser = (JSONObject) ret.getEntity();
            if (svmUser != null) {
                return String.valueOf(svmUser.get("userName"));
            }
        }
        return null;
    }

    //资金扣款，单股
    private boolean fundMove(String userSettleNo, double money) {
        String jysFundsId = Constant.getJysFundsId();//读取平台资金账号
        double amount = NumberUtil.mul(money, 100, 2);
        Map<String, String> prarmMap1 = new HashMap<String, String>();
        prarmMap1.put("tradeType", Constant.Funds.FADV);//定值
        prarmMap1.put("fromUserId", userSettleNo);//付款方账户
        prarmMap1.put("toUserId", jysFundsId);//收款方账户
        prarmMap1.put("amt", Long.toString(Math.round(amount)));//操作金额

        //添加参数组
        List<Map<String, String>> list = new ArrayList<Map<String, String>>();
        list.add(prarmMap1);
        //补充参数
        Map<String, Object> fundsMap = new HashMap<String, Object>();
        fundsMap.put("funds", list);
        fundsMap.put("actionId", "FADV-" + String.valueOf(new Date().getTime()));//业务流水号
        fundsMap.put("remark", "申购中签资金扣款");//业务描述
        ResultEntity entityFunds = FundsUtil.doFunds(fundsMap.get("remark").toString(), fundsMap);
        if ("true".equals(entityFunds.getResult()) && "true"
                .equals(entityFunds.getEntity().toString())) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public Object doInvoke(Map<String, Object> param) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Object afterInvoke(Map<String, Object> param) {
        // TODO Auto-generated method stub
        return null;
    }

    /**
     * 规则校验入口（专门给系统公式规则提供的）
     *
     * @param paramsVo
     */
    public void run(ParamsVo paramsVo) {
        beforeInvoke(paramsVo.getParams());
    }

    /**
     * 获取交易资金和中签用户名
     *
     * @param id
     * @return
     */
    public Object getPayAmount(String id) {
//        ProxyManager netProxyManager = (ProxyManager) SpringContextLoader
//                .getBean("netProxyManager");
//        ParamsVo params = new ParamsVo();
//        params.setParams("sqlKeyId", "ByObjInfo");
//        params.setKey("publicForSql");
        //		StringBuffer dyncSql = new StringBuffer(
        //				"select sum(tn.nums*tn.price) total_price,price,nums,tn.user_owner from trs_numbers tn where tn.sale_id='" + id
        //						+ "' and tn.is_select='T' group by tn.user_owner,price,nums");

        StringBuffer dyncSql = new StringBuffer(
                "select price,nums,number_id,tn.user_owner from trs_numbers tn where tn.sale_id='"
                        + id + "' and tn.is_select='T'");
//        params.setParams("dyncSql", dyncSql.toString());
        System.out.println("计算应交金额=>" + dyncSql);
//        ResultEntity dymicSqlParamResult = (ResultEntity) netProxyManager.doInvoke(params);
//        List<DataMap> list = (List) dymicSqlParamResult.getEntity();
//        List<DataMap> list = (List<DataMap>)UtilPlugin.getInstance().selectObjectForDatasource(dyncSql.toString(),"sale");
        List<DataMap> list = (List<DataMap>) IusPluginUtil.getInstance().select(dyncSql.toString(), 0, 0);
        return list;
    }

    /**
     * 付款后续操作， 传入参数活动ID（saleId），通过saleId和中签和支付成功的账号进行修改支付状态
     *
     * @return
     */
    @SuppressWarnings({"rawtypes", "unchecked"})
    public Object updatePayStatus(Map<String, Object> numbersMap) {
//        ProxyManager netProxyManager = (ProxyManager) SpringContextLoader
//                .getBean("");
//        ParamsVo params = new ParamsVo();
//        params.setParams(numbersMap);
//        params.setParams("doCode", "dymicSql");
//        params.setParams("sqlKeyId", "ByDymicSql");
//        params.setParams("resultType", "processSql");
//        params.setKey("publicForSql");
        //封装参数
//        params.setParams("modelTypes", "u_trsNumbers,u_trsBuy");
//        ResultEntity dymicSqlParamResult = (ResultEntity) .doInvoke(params);
        ResultEntity dymicSqlParamResult = UtilPlugin.getInstance().saveByParams("sale", "u_trsNumbers,u_trsBuy", numbersMap);

        return dymicSqlParamResult;
    }

}
